<template>
  <div
    class="v-slider">
    <div
      ref="slider"
      class="v-slider__runway"
      :style="{backgroundColor: runwayColor}"
      @click="_handleClickChange">
      <div
        class="v-slider__buffer-bar"
        :style="{
          width: bufferWidth,
          left: '0%',
          backgroundColor: bufferColor,
          transition: bufferTrans ? 'width 1s linear' : ''
        }">
      </div>
      <div
        class="v-slider__progress-bar"
        :style="{
          width: barWidth,
          left: '0%',
          backgroundColor: barColor
        }">
      </div>
      <slider-button
        ref="sliderButton"
        :isloading="isloading"
        v-model="dragValue">
      </slider-button>
    </div>
  </div>
</template>

<script lang="ts">
import Vue from 'vue'
import sliderButton from './SliderButton.vue'

export default Vue.extend({
  name: 'Slider',

  data () {
    return {
      dragValue: 0,
      pos: {x: 0, y: 0},
      arr: [{a: 1, b: '2'}]
    }
  },

  props: {
    min: {
      type: Number,
      default: 0
    },
    max: {
      type: Number,
      default: 100
    },
    step: {
      type: Number,
      default: 1
    },
    value: {
      type: [Number, Array],
      default: 0
    },
    bufferValue: {
      type: [Number, Array],
      default: 0
    },
    showInput: {
      type: Boolean,
      default: false
    },
    showInputControls: {
      type: Boolean,
      default: true
    },
    showStops: {
      type: Boolean,
      default: false
    },
    disabled: {
      type: Boolean,
      default: false
    },
    range: {
      type: Boolean,
      default: false
    },
    runwayColor: {
      type: String,
      default: '#e4e8f1'
    },
    bufferColor: {
      type: String,
      default: 'rgba(255, 255, 255, 0.6)'
    },
    barColor: {
      type: String,
      default: '#20a0ff'
    },
    buttonColor: {
      type: String,
      default: '#20a0ff'
    },
    buttonShadow: {
      type: Boolean,
      default: true
    },
    isloading: {
      type: Boolean,
      default: false
    },
    bufferTrans: {
      type: Boolean,
      default: true
    }
  },

  watch: {
    dragValue (val) {
      this.$emit('input', val)
    },

    value (val) {
      this.dragValue = val
    }
  },

  components: {
    sliderButton
  },

  computed: {
    bufferWidth ():string {
      return this.bufferValue + '%'
    },

    barWidth ():string {
      return this.dragValue + '%'
    },

    $sliderWidth ():number {
      return parseInt(String(window.getComputedStyle(<Element> this.$refs.slider).width))
    }
  },

  mounted () {
    this.init()
  },

  methods: {
    init () {
      const sliderDOM = <HTMLElement> this.$refs.slider
      let posX = sliderDOM.offsetLeft
      let posY = sliderDOM.offsetTop
      this.pos = {x: posX, y: posY}
    },

    setValue (val:number) {
      this.$emit('change', val || this.value)
    },

    _handleClickChange (event:any) {
      const btnWid = parseInt(String(window.getComputedStyle(document.getElementsByClassName('slider__button')[0]).width))
      let clickProgress = parseInt(String((event.clientX - this.pos.x - btnWid) / this.$sliderWidth * 100))
      if (clickProgress >= 0 && clickProgress <= 100) {
        this.$emit('input', clickProgress)
        this.setValue(clickProgress)
      }
    }
  }
})
</script>

<style scoped>

.v-slider__runway {
  width: 100%;
  height: 2px;
  margin: 6px 0;
  border-radius: 3px;
  position: relative;
  /* cursor: pointer; */
  vertical-align: middle;
}

.v-slider__buffer-bar {
  height: 2px;
  border-radius: 3px;
  position: absolute;
}

.v-slider__progress-bar {
  height: 2px;
  border-top-left-radius: 3px;
  border-bottom-left-radius: 3px;
  position: absolute;
}
</style>